﻿using System;
using System.Collections.Generic;
using System.IO;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.UI;

namespace Jinndev.Modding {

    public static class ModUtil {

        public static string Root {
            get {
                //if (Application.isMobilePlatform) {
                //    return Path.Combine(Application.persistentDataPath, "Mod");
                //}
                //else {
                //    return Path.Combine(Application.streamingAssetsPath, "Mod");
                //}
                return Path.Combine(Application.streamingAssetsPath, "Mod");
            }
        }

        public static string GetSubConfigNodeName(Type type) {
            string name = type.Name;
            if (name.Contains("Config")) {
                name = name.Replace("Config", string.Empty);
            }
            return name.Substring(0, 1).ToLower() + name.Substring(1);
        }

        //public static Type GetSubConfigByName(string name) {
        //    name += "Config";
        //    return Assembly.GetExecutingAssembly().GetType(name,false,true);
        //    //return Type.GetType("Jinndev." + name, false, true);
        //}

        public static List<string> ListModDirs() {
            List<string> result = new List<string>();
            if (ResourceManager.DirectoryExists(Root)) {
                if(Application.platform == RuntimePlatform.Android) {
                    string dir = Path.Combine(Root, "Core");
                    result.Add(dir);
                }
                else {
                    string[] dirs = Directory.GetDirectories(Root);
                    foreach (string dir in dirs) {
                        if(ResourceManager.FileExists(Path.Combine(dir, "Mod.json"))) {
                            result.Add(dir);
                        }
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 加载Mod实例，不包含配置
        /// </summary>
        /// <param name="dir">Mod所在文件夹</param>
        public static Mod LoadMod(string dir) {
            if (!ResourceManager.FileExists(dir + "/Mod.json")) {
                Debug.LogError($"Mod.json not found, \"{dir}\"");
                return null;
            }
            try {
                Mod mod = new Mod(dir);

                string json = ResourceManager.ReadAllText(dir + "/Mod.json");
                JsonUtility.FromJsonOverwrite(json, mod);

                if (string.IsNullOrWhiteSpace(mod.name)) {
                    Debug.LogError($"Mod name is required, \"{dir}\"");
                    return null;
                }
                if (mod.name.Contains(".")) {
                    Debug.LogError($"Invalid mod name \"{mod.name}\"");
                    return null;
                }

                mod.name = mod.name.Trim();
                return mod;
            }
            catch (Exception e) {
                Debug.LogException(e);
            }
            return null;
        }

        public static bool ValidateModName(string name) {
            if (string.IsNullOrWhiteSpace(name)) {
                Debug.LogError($"Mod name is empty");
                return false;
            }
            if (name.Contains(".")) {
                Debug.LogError($"Invalid mod name \"{name}\"");
                return false;
            }
            return true;
        }

        public static Mod CreateMod(string name) {
            if (!ValidateModName(name)) {
                return null;
            }
            if (!Directory.Exists(Root)) {
                Directory.CreateDirectory(Root);
            }

            string modDir = Path.Combine(Root, name);
            if (!Directory.Exists(modDir)) {
                Mod mod = new Mod(modDir);
                mod.name = name;
                return mod;
            }
            return null;
        }

        public static string GetConfigFilePath(Mod mod, ConfigEntry entry, string suffix) {
            string fileName = entry.fileNamePrefix;
            if (!string.IsNullOrWhiteSpace(suffix)) {
                fileName += "_" + suffix;
            }
            fileName += ".json";

            return Path.Combine(Root, mod.name, "Config", fileName);
        }

        public static void SetConfigIcon(RawImage image, int id) {
            if (image == null) {
                return;
            }
            Config config = ModManager.GetConfig(id);
            Config.Icon icon = config == null ? null : config.GetIcon();
            SetConfigIcon(image, icon);
        }

        public static void SetConfigIcon(RawImage image, IConfigIcon configIcon) {
            if (image == null) {
                return;
            }
            Config.Icon icon = configIcon == null ? null : configIcon.GetIcon();
            SetConfigIcon(image, icon);
        }

        public static void SetConfigIcon(RawImage image, Config.Icon icon) {
            if (image == null) {
                return;
            }
            if (icon != null && icon.texture != null) {
                image.texture = icon.texture;
                image.uvRect = icon.rect;
                image.rectTransform.anchoredPosition = icon.offset * new float2(image.rectTransform.rect.size);
                return;
            }
            image.texture = null;
            image.uvRect = new Rect(0, 0, 1, 1);
        }

    }

}